package com.sdhs.paas.sso.sp;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import com.sdhs.paas.internet.util.ContextHelper;
import com.sdhs.paas.internet.util.RequestURIFilter;

public class SsoAuthenticaitonFilter implements Filter {
	/**
	 * 日志组件
	 */
	private static Logger log = Logger.getLogger(SsoAuthenticaitonFilter.class);

	/**
	 * 上下文信息
	 */
	private ServletContext sc;

	/**
	 * 此Filter放行（不过滤）的文件集合
	 */
	private RequestURIFilter excludes;

	/**
	 * Filter配置
	 */
	private FilterConfig filterConfig;

	private String notFilterDir = "";
	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
		sc = filterConfig.getServletContext();
		String excludes =  this.filterConfig.getInitParameter("excludes");
		notFilterDir =  this.filterConfig.getInitParameter("notFilterDir");
		this.setExcludes(excludes);
	}
	public void setExcludes(String excludes) {
		this.excludes = new RequestURIFilter(excludes);
	}

	public void doFilter(ServletRequest servletRequest,
			ServletResponse servletResponse, FilterChain filterChain)
			throws IOException, ServletException {
		String sso_type = SsoUtil.getValue("sso_type");
		if("samlsso".equals(sso_type)) {
			executeSaml(servletRequest, servletResponse, filterChain);
		}else{
			executeSaml(servletRequest, servletResponse, filterChain);
//			filterChain.doFilter(servletRequest, servletResponse);
//			executeLam(servletRequest, servletResponse, filterChain);
		}
	}


	public void destroy() {
	}
	
	/**
	 * 跳转IDP端进行登录授权
	 * 
	 * @param request
	 * @param response
	 */
	public void doLogin(HttpServletRequest request, HttpServletResponse response) {
		try {
			PrintWriter out = response.getWriter();

			StringBuffer curUrl = request.getRequestURL();// 获取当前url
			request.getSession().setAttribute("RelayState", curUrl.toString());// 保存当前url，用于IDP端登录后，自动跳转到该url

			String loginSamlUrl = SsoUtil.getValue("login_saml_url");// 获取saml单点登录认证url
			response.setHeader(
					"P3P",
					"CP=\"CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR\"");

			String AssertionConsumerServiceURL = "http://"
					+ request.getServerName() + ":" + request.getServerPort()
					+ request.getContextPath() + "/UserAction";// 设置sp端对应的登录授权url（用与在IDP端成功认证后，跳转到sp端进行登录授权）

			StringBuffer form = new StringBuffer();
			form.append(
					"<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><title>loading...</title></head><body onload='document.forms[0].submit()'><form action=\"")
					.append(loginSamlUrl+"?SAMLRequest="+AssertionConsumerServiceURL)
					.append("\" method=\"get\"></form></body></html>");

			out.write(form.toString());
			out.flush();
			out.close();
		} catch (Exception ex) {
			log.error("saml 调整登录失败!" + ex);
		}
	}
	
	/**
	 * 处理saml登录方式
	 * @param servletRequest
	 * @param servletResponse
	 * @param filterChain
	 */
	private void executeSaml(ServletRequest servletRequest,
			ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException{
		HttpServletRequest req = (HttpServletRequest) servletRequest;
		HttpServletResponse res = (HttpServletResponse) servletResponse;
		ContextHelper.init(req, res, sc);
		/**************** 直接访问业务系统域名时，放行 ************/
		String sysDomainUrl = SsoUtil.getValue("sys_domain_url");
		if("/".equals(req.getRequestURI()) || sysDomainUrl.endsWith(req.getRequestURI())){
			filterChain.doFilter(servletRequest, servletResponse);
			return;
		}
		/**************** 放行不需要过滤的路径 ************/
		if (req.getRequestURI().indexOf(notFilterDir) >= 0) {
			filterChain.doFilter(servletRequest, servletResponse);
			return;
		}

		/**************** 放行不需要过滤的文件 ************/
		if (this.excludes.matches(req)) {
			filterChain.doFilter(servletRequest, servletResponse);
			return;
		}

		HttpSession session = req.getSession(false);
		if (session == null) {
			session = req.getSession(true);
		}
		/**************** 取对应sp端登录成功后保存到session对象中的属性 ******************/
		Object userLoginInfo = session.getAttribute("UserLoginInfo");
		if (userLoginInfo == null) {// sp端未登录
			doLogin(req, res);// 跳转IDP端进行登录授权
		} else {
			filterChain.doFilter(servletRequest, servletResponse);
		}
	}

}